#include<vector>
#include<mutex>
#include<condition_variable>
using namespace std;
class ProduceConsume {
private:
	vector<int>buffer;
	int size;
	int front;
	int rear;

	mutex mx;
	condition_variable p_cond;
	condition_variable c_cond;

	bool isEmpty() {
		return front == rear;
	}
	bool isFull() {
		return (rear + 1) % size == front;
	}

public:
	ProduceConsume(int bs) :
		buffer(bs+1), size(bs+1),
		front(0), rear(0) {

	}

	void produce(int val) {
		unique_lock<mutex> lock(mx);
		p_cond.wait(lock, [&]() {return !isFull(); });
		buffer[rear] = val;
		rear = (rear + 1) % size;
		c_cond.notify_one();
	}

	int consume() {
		unique_lock<mutex> lock(mx);
		c_cond.wait(lock, [&]() {return !isEmpty(); });
		int val=buffer[front];
		front = (front + 1) % size;
		p_cond.notify_one();
		return val;
	}
};